home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 May / EnigmA AMIGA RUN 18 (1997)(G.R. Edizioni)(IT)[!][issue 1997-05][EAR-CD II].iso / earcd / gfx / fract / lfracs.lha / LFracs-Source.lha / LFracs-Source / LFracs.c < prev    next >
C/C++ Source or Header  |  1997-01-06  |  27KB  |  677 lines

  1. /*****************************************************************************/
  2. /* LFracs.c                Programm zum Zeichnen von L-Fraktalen             */
  3. /*****************************************************************************/
  4.  
  5. /*** Includes ****************************************************************/
  6. #include "StdInc.h"     /* Enthält alle wichtigen C-Include-Dateien          */
  7. #include "StdFuncs.h"   /* Enthält open_libs,close_libs,open_window,cls      */
  8. #include "GuiFuncs.h"   /* Enthält start_GUI,end_GUI,loop_GUI,               */
  9.                         /*         start_busy,end_busy,fill_tag,             */
  10.                         /*         make_text,make_gadget,make_req,           */
  11.                         /*         get_gadadr,get_STGADinfo,set_STGADinfo,   */
  12.                         /*         add_menu,init_menu,destroy_menu           */
  13.                         /*         destroy_gadlist,destroy_req,              */
  14.                         /*         open_catalog,get_catstr,close_catalog     */
  15. #include "IoFuncs.h"    /* Enthält win_print                                 */
  16.  
  17. UBYTE vers[]="$VER: LFracs 1.0 (27.12.96)";
  18.  
  19. /*** Prototypes **************************************************************/
  20. void do_menu(Item item,Event event);
  21. void new_code(Item item,Event event);
  22. void generator(Item item,Event event);
  23. void plotter(void);
  24. void quit(char *error_text);
  25. void load_screen(Item item,Event event);
  26. void save_screen(Item item,Event event);
  27. void printer(Item item,Event event);
  28. void load_code(Item item,Event event);
  29. void save_code(Item item,Event event);
  30. void dir_code(Item item,Event event);
  31.  
  32. /*** Globale Standard-Variablen **********************************************/
  33. struct Window   *Window = NULL;
  34. struct RastPort *rp     = NULL;
  35.  
  36. /*** Globale Konstanten ******************************************************/
  37. #define AXIOMSIZE    32000L
  38. #define STRINGSIZE      30
  39. #define DATANAMESIZE    60
  40. #define DEPTH_SIZE       3
  41. #define PLOT_SIZE        4
  42. #define CODEZAHL         7
  43.  
  44. /*** Datentypen für generator() und plotter() [siehe auch new_trigo()] *******/
  45. struct Axiom       {
  46.                     UBYTE astr[AXIOMSIZE];
  47.                     struct Axiom *next;
  48.                    };
  49. struct TrigoData   {
  50.                     float xschw,yschw;
  51.                     struct TrigoData *prev,*next;
  52.                    };
  53. struct Verzweigung {
  54.                     float xcoord,ycoord;
  55.                     struct TrigoData *trigo;
  56.                    };
  57.  
  58. /*** Weitere globale Variablen ***********************************************/
  59. enum {PLUS=1,MINUS,
  60.       LBRACKET,RBRACKET,FORWARD,CODE1};         /* Standard Code-Bezeichner  */
  61. SHORT begdepth;                                 /* Aktuelle Generator-Tiefe  */
  62. struct Axiom *axiom,*sax;                       /* Axiom, Axiom-zw.-Speicher */
  63.  
  64. /*** Menu-Data ***************************************************************/
  65. struct Menu *menu = NULL;
  66. enum {NEW,QUIT,DRAW,LOAD,SAVE,PRINT};                          /* Menu-Items */
  67. struct GuiMenudata project_data[2] = {{NULL,NEW,do_menu},
  68.                                       {NULL,QUIT,do_menu}};
  69. struct GuiMenudata picture_data[4] = {{NULL,DRAW,do_menu},
  70.                                       {NULL,LOAD,load_screen},
  71.                                       {NULL,SAVE,save_screen},
  72.                                       {NULL,PRINT,printer}};
  73.  
  74. /*** Gadget- und Requester-Data **********************************************/
  75. struct Requester new_req,plot_req;                        /* Requester       */
  76. struct FileRequester *file_req = NULL;                    /* ASL-Requester   */
  77. enum {NEW_GADLIST,PLOT_GADLIST,NEW_CONTXT,PLOT_CONTXT,    /* GadTools-GLists */
  78.       NEW_OK_GAD,PLOT_OK_GAD,CANCEL_GAD,DIR_GAD,SAVE_GAD, /* Gadgets         */
  79.       DEPTH_GAD,SCHW_GAD,DWIN_GAD,KOORD_GAD0,KOORD_GAD1,
  80.       WIN_GAD,NAME_GAD,AXIOM_GAD,CODE_GAD};
  81.  
  82. /*** Locale-Data (wird von GuiFuncs benötigt) ********************************/
  83. enum {OK_STR,CANCEL_STR,RETRY_STR,DIR_STR,SAVE_STR,YES_STR,NOTYET_STR,
  84.       PROJECT_STR,NEW_STR,QUIT_STR,
  85.       PICTURE_STR,DRAW_STR,LOAD_STR,MSAVE_STR,PRINT_STR,
  86.       FILE_STR,STEP_STR,TURN_STR,STARTANGLE_STR,DEPTH_STR,STARTPT_STR,
  87.       CODEINPUT_STR,GENPIC_STR,
  88.       SELCODEFILE_STR,LOADPIC_STR,SAVEPIC_STR,
  89.       PRINTOK_STR,QUITOK_STR,OUTOFMEM_STR};
  90. char *default_catstr[OUTOFMEM_STR+1] = {
  91.            "OK","CANCEL","RETRY","DIR","SAVE","YES","NOT YET",
  92.            "Project","New..._N","Quit_Q",
  93.            "Picture","Draw..._D","Load..._L","Save..._S","Print_P",
  94.            "File:","Step:","Turn:","Startangle:","Depth:","Startpt (x,y):",
  95.            "Code-Input:","Generate Picture:",
  96.            "Select Code-File","Load Picture","Save Picture",
  97.            "Ready to Print?","Quit really?","Out of Memory!"
  98.      };
  99.  
  100. /*** Globale Arrays **********************************************************/
  101. UBYTE title[STRINGSIZE];                                 /* Window-Title     */
  102. UBYTE code[CODE1+CODEZAHL][STRINGSIZE];                  /* Codes            */
  103. UBYTE code_buc[CODE1+CODEZAHL]={0,'+','-','(',')','f'};  /* Code-Bezeichner  */
  104. char  code_title[CODEZAHL][10];                          /* CodeGadget-Titel */
  105. char *ok_title,*cancel_title,*save_title,*dir_title,
  106.      *schw_title,*dwin_title,*win_title,*depth_title,*koord_title;
  107.  
  108. /*****************************************************************************/
  109. /* prod_GUI  (Erzeugt alle Menus, Gadgets und Requester außer ASL-Requester) */
  110. /*****************************************************************************/
  111. void prod_GUI(void)
  112. {
  113.  COUNT i;
  114.  short gadh,gadw,nam_gadx,plot_reqw;
  115.  char  koord_info[PLOT_SIZE];
  116.  
  117.    add_menu(&menu,get_catstr(PROJECT_STR),2,project_data);
  118.    add_menu(&menu,get_catstr(PICTURE_STR),4,picture_data);
  119.    init_menu(Window,menu);
  120.    set_gaps(14,3); gadh=5+fheight(1); gadw=fwidth(5);
  121.    nam_gadx = 20+tlength(save_title)+30+tlength("Code 5:");
  122.  
  123.    make_gadlist(NEW_GADLIST,NEW_CONTXT);
  124.    make_gadget(SAVE_GAD,BUTTON_KIND,0,20,12+fheight(1),
  125.                tlength(save_title)+4,gadh,
  126.                get_catstr(SAVE_STR),NULL,0,NEW_CONTXT,save_code);
  127.    make_gadget(DIR_GAD,BUTTON_KIND,0,relX(0),relY(1),
  128.                tlength(save_title)+4,gadh,
  129.                get_catstr(DIR_STR),NULL,0,SAVE_GAD,dir_code);
  130.    make_gadget(NEW_OK_GAD,BUTTON_KIND,GACT_ENDGADGET,relX(0),relY(1)+8,
  131.                tlength(save_title)+4,3+gadh,ok_title,NULL,0,DIR_GAD,new_code);
  132.    make_gadget(NAME_GAD,STRING_KIND,0,nam_gadx,12+fheight(1),fwidth(30),gadh,
  133.                get_catstr(FILE_STR),NULL,STRINGSIZE,NEW_OK_GAD,load_code);
  134.    make_gadget(AXIOM_GAD,STRING_KIND,0,nam_gadx,relY(1),
  135.                fwidth(30),gadh,"Axiom:",NULL,STRINGSIZE,NAME_GAD,NULL);
  136.  
  137.   for(i=0;i<CODEZAHL;i++) {
  138.      sprintf((char *)code_title[i],"Code %d:",(long) i+1);
  139.      make_gadget(CODE_GAD+i,STRING_KIND,0,
  140.                  nam_gadx,relY(1),fwidth(30),gadh,
  141.                  (char *)code_title[i],NULL,STRINGSIZE,CODE_GAD+i-1,NULL);
  142.   }
  143.  
  144.    make_gadlist(PLOT_GADLIST,PLOT_CONTXT);
  145.    make_gadget(SCHW_GAD,STRING_KIND,LONGINT,10+tlength(schw_title),12+fheight(1),
  146.                gadw,gadh,schw_title,"20",PLOT_SIZE,PLOT_CONTXT,NULL);
  147.    make_gadget(DWIN_GAD,STRING_KIND,LONGINT,relX(1)+tlength(dwin_title),
  148.                relY(0),gadw,gadh,dwin_title,"90",PLOT_SIZE,SCHW_GAD,NULL);
  149.    make_gadget(WIN_GAD,STRING_KIND,LONGINT,relX(1)+tlength(win_title),
  150.                relY(0),gadw,gadh,win_title,"0",PLOT_SIZE,DWIN_GAD,NULL);
  151.    make_gadget(DEPTH_GAD,STRING_KIND,LONGINT|GACT_ENDGADGET,
  152.                10+tlength(depth_title),relY(1)+3,fwidth(4),gadh,
  153.                depth_title,NULL,DEPTH_SIZE,WIN_GAD,generator);
  154.    sprintf((char *)koord_info,"%d",OScanWidth/2);
  155.    make_gadget(KOORD_GAD0,STRING_KIND,LONGINT,relX(1)+tlength(koord_title),relY(0),
  156.                gadw,gadh,koord_title,koord_info,PLOT_SIZE,DEPTH_GAD,NULL);
  157.    sprintf((char *)koord_info,"%d",OScanHeight/2);
  158.    make_gadget(KOORD_GAD1,STRING_KIND,LONGINT,relX(1)-12,relY(0),
  159.                gadw,gadh,NULL,koord_info,PLOT_SIZE,KOORD_GAD0,NULL);
  160.    make_gadget(PLOT_OK_GAD,BUTTON_KIND,GACT_ENDGADGET,35,relY(1)+10,
  161.                gadw,2+gadh,ok_title,NULL,0,KOORD_GAD1,generator);
  162.    make_gadget(CANCEL_GAD,BUTTON_KIND,GACT_ENDGADGET,40+fwidth(20),relY(0),
  163.                tlength(cancel_title)+16,2+gadh,cancel_title,NULL,0,PLOT_OK_GAD,NULL);
  164.  
  165.   make_req(&new_req,(OScanWidth-fwidth(30)-nam_gadx-16)/2,
  166.            OScanHeight/2-fheight(3+CODEZAHL)/2-4*CODEZAHL-20,
  167.            fwidth(30)+nam_gadx+16,40+8*CODEZAHL+fheight(3+CODEZAHL),
  168.            NEW_GADLIST,make_text(get_catstr(CODEINPUT_STR),10,5,1,NULL),0);
  169.   plot_reqw = 20+tlength(schw_title)+tlength(dwin_title)+tlength(win_title)+
  170.               gadw*3+14*2;
  171.   make_req(&plot_req,(OScanWidth-plot_reqw)/2,(OScanHeight-fheight(4)-64)/2,
  172.            plot_reqw,fheight(4)+64,PLOT_GADLIST,
  173.            make_text(get_catstr(GENPIC_STR),10,5,1,NULL),0);
  174. }
  175.  
  176. void activate_gad(USHORT gad_id,struct Requester *req)
  177. {ActivateGadget(get_gadadr(gad_id),Window,req);}
  178.  
  179. void do_menu(Item item,Event event)
  180. {
  181.   switch(item) {
  182.     case QUIT: if(bool_request(Window,get_catstr(QUITOK_STR),
  183.                                get_catstr(YES_STR),get_catstr(NOTYET_STR)))
  184.                   quit(NULL);
  185.                break;
  186.     case NEW: show_req(&new_req,Window); activate_gad(NAME_GAD,&new_req);break;
  187.     case DRAW: show_req(&plot_req,Window); activate_gad(DEPTH_GAD,&plot_req);break;
  188.   }
  189. }
  190.  
  191. void std_title(void)
  192. {
  193.    sprintf((char *)title,"LFracs: %s",get_STGADinfo(NAME_GAD));
  194.    SetTitle(Window,title);
  195. }
  196.  
  197. /*****************************************************************************/
  198. /* init_locale (Öffnet Locale-Catalog und liest lokalisierte Strings aus)    */
  199. /*****************************************************************************/
  200. void init_locale(void)
  201. {
  202.    open_catalog("LFracs.catalog",default_catstr);
  203.  
  204.    project_data[0].name = get_catstr(NEW_STR);
  205.    project_data[1].name = get_catstr(QUIT_STR);
  206.    picture_data[0].name = get_catstr(DRAW_STR);
  207.    picture_data[1].name = get_catstr(LOAD_STR);
  208.    picture_data[2].name = get_catstr(MSAVE_STR);
  209.    picture_data[3].name = get_catstr(PRINT_STR);
  210.  
  211.    ok_title    = get_catstr(OK_STR);    cancel_title = get_catstr(CANCEL_STR);
  212.    save_title  = get_catstr(SAVE_STR);  dir_title    = get_catstr(DIR_STR);
  213.    schw_title  = get_catstr(STEP_STR);  dwin_title   = get_catstr(TURN_STR);
  214.    depth_title = get_catstr(DEPTH_STR); koord_title  = get_catstr(STARTPT_STR);
  215.    win_title   = get_catstr(STARTANGLE_STR);
  216. }
  217.  
  218. /*****************************************************************************/
  219. /* Main()  (Hauptprogramm - Erzeugt Window, Menüs..., startet Main-Loop)     */
  220. /*****************************************************************************/
  221. void main(void)
  222. {
  223.    open_libs(INTUITION_LIB|GRAPHICS_LIB|MATHFFP_LIB|MATHTRANS_LIB|
  224.              GADTOOLS_LIB|ASL_LIB|UTILITY_LIB|LOCALE_LIB);
  225.  
  226.    init_locale(); start_GUI();
  227.    Window = open_window(0,fheight(1)+3,OScanWidth,OScanHeight-fheight(1)-3,
  228.                         "LFracs",WFLG_ACTIVATE|WFLG_CLOSEGADGET|
  229.                         WFLG_DRAGBAR|WFLG_HASZOOM|WFLG_DEPTHGADGET,
  230.                         IDCMP_CLOSEWINDOW|IDCMP_GADGETUP|IDCMP_MENUPICK|
  231.                         IDCMP_NEWSIZE,NULL);
  232.    if(Window==NULL) quit("Couldn't open the Main-Window");
  233.  
  234.    prod_GUI();
  235.    file_req = (struct FileRequester *) AllocAslRequestTags(ASL_FileRequest,
  236.                                                ASL_Dir,"FracsCodes",TAG_END);
  237.    rp=Window->RPort;
  238.    SetDrMd(rp,JAM1);
  239.    SetAPen(rp,1L);
  240.  
  241.    axiom = (struct Axiom *) malloc(sizeof(struct Axiom));
  242.    sax   = (struct Axiom *) malloc(sizeof(struct Axiom));
  243.    if((axiom==NULL)||(sax==NULL)) quit(get_catstr(OUTOFMEM_STR));
  244.    else {axiom->next=NULL; sax->next=NULL;}
  245.  
  246.    show_req(&new_req,Window);                  /* Rufe Eingabe-Requester auf */
  247.    activate_gad(NAME_GAD,&new_req);
  248.    loop_GUI(Window);                           /* und warte auf Antwort      */
  249.    quit(NULL);                                 /* MainLoop-Ende => Quit      */
  250. }
  251.  
  252. /*****************************************************************************/
  253. /* code_translate  (Übersetzt Eingabe-Codestrings in eine kompaktere Form)   */
  254. /*****************************************************************************/
  255. void code_translate(UBYTE *code_str)
  256. {
  257.  COUNT i;
  258.  
  259.   while(*code_str!=0) {
  260.     for(i=PLUS;i<=FORWARD+CODEZAHL;i++)
  261.       if(code_buc[i]==*code_str) {*code_str=(UBYTE) i; break;}
  262.     if(i>FORWARD+CODEZAHL) *code_str=0;
  263.      code_str++;
  264.   }
  265. }
  266.  
  267. /*****************************************************************************/
  268. /* new_code  (Bearbeitet User-Eingaben im Eingabe-Requester)                 */
  269. /*****************************************************************************/
  270. void new_code(Item item,Event event)
  271. {
  272.  COUNT i;
  273.  BOOL  newfwd = FALSE;
  274.  UBYTE *gad_info;
  275.  
  276.    begdepth=1; set_STGADinfo(DEPTH_GAD,(UBYTE *) ""); std_title();
  277.  
  278.   for(i=0;i<=FORWARD;i++) {code[i][0]=i; code[i][1]=0;}
  279.  
  280.   for(i=0;i<CODEZAHL;i++) {
  281.      gad_info=get_STGADinfo(CODE_GAD+i);
  282.      code_buc[CODE1+i]=*gad_info;
  283.     if(*gad_info!=0) strcpy((char *)code[CODE1+i],(char *)gad_info+2);
  284.     else             strcpy((char *)code[CODE1+i],"");
  285.     if(*gad_info=='f') {
  286.        newfwd=TRUE; strcpy((char *)code[FORWARD],(char *)code[CODE1+i]);
  287.     }
  288.   }
  289.  
  290.   if(newfwd) code_translate(code[FORWARD]);
  291.   for(i=CODE1;i<CODE1+CODEZAHL;i++) code_translate(code[i]);
  292.  
  293.   show_req(&plot_req,Window);                 /* Rufe Zeichnen-Requester auf */
  294.   activate_gad(DEPTH_GAD,&plot_req);
  295. }
  296.  
  297. /*****************************************************************************/
  298. /* ..._axiom() - Funktionen (Um den Speicherbedarf der axiom/sax-Strings zu  */
  299. /*                           halbieren, werden in ein Byte zwei Codezeichen  */
  300. /*                           [es gibt <=5+CODEZAHL<16 versch.] geschrieben.  */
  301. /*                           Die folgenden Funktionen erleichtern den Umgang */
  302. /*                           mit diesen besonderen Strings)                  */
  303. /*****************************************************************************/
  304. UBYTE get_nextaxiom(UBYTE **aptr, BOOL *right_part)
  305. {
  306.    *right_part = !(*right_part);
  307.   if(*right_part)  return ((**aptr)&15);
  308.   else {(*aptr)++; return ((**aptr)>>4);}
  309. }
  310.  
  311. void set_axiom(UBYTE **aptr, BOOL *right_part, UBYTE *scode)
  312. {
  313.  UBYTE *code_ptr;
  314.  
  315.    code_ptr=scode;
  316.   if(*right_part) {
  317.      **aptr = (**aptr) | *code_ptr;
  318.      code_ptr++; (*aptr)++;
  319.   }
  320.   while(*code_ptr) {
  321.      **aptr = ((*code_ptr)<<4) | *(++code_ptr);
  322.     if(*code_ptr==0) {*right_part=TRUE; return;}
  323.      (*aptr)++; code_ptr++;
  324.   }
  325.    **aptr=0; *right_part=FALSE;
  326. }
  327.  
  328. /*****************************************************************************/
  329. /* destroy_axiom  (Gibt den Speicher der Axiom-Liste aptr wieder frei)       */
  330. /*****************************************************************************/
  331. void destroy_axiom(struct Axiom *aptr)
  332. {
  333.   if(aptr!=NULL) {destroy_axiom(aptr->next); free(aptr);}
  334. }
  335.  
  336. /*****************************************************************************/
  337. /* generator  (Generiert das L-Fractal auf dem String axiom aus den Codes)   */
  338. /*****************************************************************************/
  339. void generator(Item item,Event event)
  340. {
  341.  COUNT i;
  342.  struct Axiom *axiom_act,*sax_act,*hptr;
  343.  UBYTE *axiom_ptr,*sax_ptr,*sax_max,trans_str[STRINGSIZE],avalue;
  344.  SHORT enddepth;
  345.  BOOL  axiom_rpart,sax_rpart;
  346.  
  347.    enddepth=(SHORT) atoi((char *)get_STGADinfo(DEPTH_GAD));
  348.   if(enddepth<begdepth-1) begdepth=1;
  349.  
  350.   if(begdepth==1) {
  351.      strcpy((char *)trans_str,(char *)get_STGADinfo(AXIOM_GAD));
  352.      code_translate(trans_str);
  353.      axiom_ptr=axiom->astr; axiom_rpart=FALSE;
  354.      set_axiom(&axiom_ptr,&axiom_rpart,trans_str);
  355.      destroy_axiom(axiom->next); axiom->next=NULL;
  356.      destroy_axiom(sax->next); sax->next=NULL;
  357.   }
  358.  
  359.  while(begdepth <= enddepth)
  360.  {
  361.    sprintf((char *)title,"Generating %d of %d",(long) begdepth,(long) enddepth);
  362.    SetTitle(Window,title);
  363.    sax_act = sax; sax_ptr = sax_act->astr;
  364.    sax_rpart=FALSE; *sax_ptr=0;
  365.    sax_max = sax_ptr+AXIOMSIZE-STRINGSIZE;
  366.  
  367.   for(axiom_act=axiom;axiom_act!=NULL;axiom_act=axiom_act->next) {
  368.      axiom_ptr=axiom_act->astr; axiom_rpart=FALSE;
  369.      avalue = (*axiom_ptr)>>4;
  370.     while(avalue) {
  371.        set_axiom(&sax_ptr,&sax_rpart,code[avalue]);
  372.       if(sax_ptr > sax_max) {
  373.         if(sax_act->next == NULL) {
  374.           while(!(sax_act->next = (struct Axiom *) malloc(sizeof(struct Axiom))))
  375.             if(!bool_request(Window,get_catstr(OUTOFMEM_STR),
  376.                              get_catstr(RETRY_STR),cancel_title))
  377.                return();
  378.            sax_act->next->next = NULL;
  379.         }
  380.          sax_act = sax_act->next; sax_rpart=FALSE;
  381.          sax_ptr = sax_act->astr; *sax_ptr=0;
  382.          sax_max = sax_ptr+AXIOMSIZE-STRINGSIZE;
  383.       }
  384.       if(read_message(Window)) {std_title();return();}
  385.        avalue=get_nextaxiom(&axiom_ptr,&axiom_rpart);
  386.     }
  387.   }
  388.    hptr=sax; sax=axiom; axiom=hptr;
  389.    begdepth++;
  390.  }
  391.   std_title(); plotter();
  392. }
  393.  
  394. /*****************************************************************************/
  395. /* new_trigo u. del_trigo  (Werden v. plotter() zum Werte-Speichern benutzt) */
  396. /*****************************************************************************/
  397. struct TrigoData *new_trigo(SHORT win, SHORT schw)
  398. {
  399.  struct TrigoData *trigo;
  400.  
  401.    trigo=(struct TrigoData *) malloc(sizeof(struct TrigoData));
  402.    trigo->xschw = (float)schw*(float)cos((double)(win*PI/180.0))*0.1;
  403.    trigo->yschw = (float)schw*(float)sin((double)(win*PI/180.0))*0.1;
  404.  
  405.  return (trigo);
  406. }
  407.  
  408. void del_trigo(struct TrigoData *trigo)
  409. {
  410.  struct TrigoData *tri_ptr,*tri_next;
  411.  
  412.   if(trigo!=NULL) {
  413.      tri_ptr=trigo->next; trigo->next=NULL;
  414.     while(tri_ptr!=NULL) {
  415.        tri_next=tri_ptr->next;
  416.        free(tri_ptr); tri_ptr=tri_next;
  417.     }
  418.   }
  419. }
  420.  
  421. /*****************************************************************************/
  422. /* plotter  (Zeichnet das L-Fractal nach dem String axiom aus generator())   */
  423. /*****************************************************************************/
  424. void plotter(void)
  425. {
  426.  struct Axiom *axiom_act;
  427.  struct Verzweigung node[150],*node_ptr;
  428.  struct TrigoData *tri_first,*tri_ptr,*tri_old;
  429.  UBYTE *axiom_ptr,avalue;
  430.  SHORT schw,dwin,startwin,winkel;
  431.  float x,y;
  432.  BOOL  rpart;
  433.  
  434.    node_ptr = node;
  435.    dwin     = (SHORT) atoi((char *)get_STGADinfo(DWIN_GAD));
  436.    schw     = (SHORT) atoi((char *)get_STGADinfo(SCHW_GAD));
  437.    startwin = (SHORT) atoi((char *)get_STGADinfo(WIN_GAD));
  438.    x        = (float) atoi((char *)get_STGADinfo(KOORD_GAD0));
  439.    y        = (float) atoi((char *)get_STGADinfo(KOORD_GAD1));
  440.    dwin=(dwin+360)%360; startwin=(startwin+360)%360;
  441.  
  442.    tri_first=new_trigo(startwin,schw); tri_old=tri_first;
  443.   for(winkel=startwin+dwin;(winkel%360)!=startwin;winkel=(winkel+dwin)%360) {
  444.      tri_ptr=new_trigo(winkel,schw);
  445.      tri_ptr->prev=tri_old; tri_old->next=tri_ptr;
  446.      tri_old=tri_ptr;
  447.   }
  448.   tri_old->next=tri_first; tri_first->prev=tri_old;
  449.   tri_ptr=tri_first;
  450.  
  451.   SetTitle(Window,(UBYTE *) "Drawing..."); cls(Window);
  452.   Move(rp,(long) x,(long) y);
  453.   x/=Scale;
  454.  
  455.  for(axiom_act=axiom;axiom_act!=NULL;axiom_act=axiom_act->next) {
  456.     rpart=FALSE; axiom_ptr=axiom_act->astr;
  457.     avalue = (*axiom_ptr)>>4;
  458.    while(avalue)
  459.    {
  460.      switch (avalue) {
  461.        case PLUS:     tri_ptr=tri_ptr->next; break;
  462.        case MINUS:    tri_ptr=tri_ptr->prev; break;
  463.        case FORWARD:  x+=tri_ptr->xschw;
  464.                       y-=tri_ptr->yschw;
  465.                       Draw(rp,(long) (x*Scale),(long) y); break;
  466.        case LBRACKET: node_ptr->xcoord=x; node_ptr->ycoord=y;
  467.                       node_ptr->trigo=tri_ptr;
  468.                       node_ptr++; break;
  469.        case RBRACKET: node_ptr--;
  470.                       x=node_ptr->xcoord; y=node_ptr->ycoord;
  471.                       tri_ptr=node_ptr->trigo;
  472.                       Move(rp,(long) (x*Scale),(long) y); break;
  473.      }
  474.      if(read_message(Window)) {del_trigo(tri_ptr); std_title(); return();}
  475.       avalue=get_nextaxiom(&axiom_ptr,&rpart);
  476.    }
  477.  }
  478.   del_trigo(tri_ptr); std_title();
  479. }
  480.  
  481. /*****************************************************************************/
  482. /* quit  (Beendet das Programm - Vorher werden alle dyn. Daten gelöscht)     */
  483. /*****************************************************************************/
  484. void quit(char *error_text)
  485. {
  486.    destroy_axiom(axiom); destroy_axiom(sax);
  487.    if(file_req) FreeAslRequest((APTR) file_req);
  488.    destroy_menu(Window);
  489.    if(Window) CloseWindow(Window);
  490.    destroy_gadlist(NEW_GADLIST); destroy_gadlist(PLOT_GADLIST);
  491.    destroy_req(&new_req); destroy_req(&plot_req);
  492.    end_GUI();
  493.    close_catalog();
  494.    close_libs();
  495.  
  496.    if(error_text) {printf("%s\n",error_text); exit(FALSE);}
  497.    else                                       exit(TRUE);
  498. }
  499.  
  500. /*****************************************************************************/
  501. /* load/save_screen  (Lädt, oder speichert ein Fractal-Bild)                 */
  502. /*****************************************************************************/
  503. void load_screen(Item item,Event event)
  504. {
  505.  COUNT x,y;
  506.  ULONG pic_handle;
  507.  UBYTE dateiname[DATANAMESIZE];
  508.  SHORT win_left,win_right,win_top;
  509.  SHORT pic_scale,color=0,pix_anzahl;
  510.  float scaler;
  511.  
  512.    win_left=4; win_right=OScanWidth-5; win_top=11;
  513.  
  514.   if (AslRequestTags((APTR) file_req,ASL_Dir,(ULONG)"FracsPictures",
  515.                                      ASL_Hail,(ULONG)get_catstr(LOADPIC_STR),
  516.                                      ASL_Pattern,(ULONG)"#?.lfpic",
  517.                                      ASL_File,0L,TAG_END))
  518.   {
  519.      sprintf((char *)dateiname,"%s/%s",
  520.              (char *) file_req->rf_Dir,(char *) file_req->rf_File);
  521.  
  522.      start_busy(Window);  /* Make Window Busy */
  523.  
  524.     if(pic_handle=Open(dateiname,MODE_OLDFILE)) {
  525.        SetTitle(Window,(UBYTE *) "Loading...");
  526.        Read(pic_handle,&pic_scale,2L);
  527.        Read(pic_handle,&win_right,2L);
  528.        scaler=((float)Scale)/((float)pic_scale);
  529.        x=win_left-1; y=win_top;
  530.        Move(rp,win_left,win_top);
  531.       while (Read(pic_handle,&pix_anzahl,2L)) {
  532.          color = pix_anzahl & 1L;
  533.          x+=(pix_anzahl>>1);
  534.         if(color) Draw(rp,(SHORT)((x-win_left)*scaler+win_left),y);
  535.         Move(rp,(SHORT)((x+1-win_left)*scaler+win_left),y);
  536.         if(x==win_right) {
  537.            x=win_left-1; y++;
  538.            Move(rp,win_left,y);
  539.         }
  540.       }
  541.        Close(pic_handle);
  542.     }
  543.      end_busy(Window); std_title();   /* Unbusy Window */
  544.   }
  545. }
  546.  
  547. void save_screen(Item item,Event event)
  548. {
  549.  COUNT x,y;
  550.  ULONG pic_handle;
  551.  UBYTE dateiname[DATANAMESIZE],vorschlag[STRINGSIZE];
  552.  SHORT win_left,win_right,win_top,win_bottom;
  553.  SHORT color=0,pix_anzahl,xlast;
  554.  
  555.    win_left = 4;  win_right  = OScanWidth-5;
  556.    win_top  = 11; win_bottom = OScanHeight-3;
  557.  
  558.    sprintf((char *)vorschlag,"%s%d.lfpic",get_STGADinfo(NAME_GAD),begdepth-1);
  559.  
  560.   if (AslRequestTags((APTR) file_req,ASL_Dir,(ULONG)"FracsPictures",
  561.                                      ASL_Hail,(ULONG)get_catstr(SAVEPIC_STR),
  562.                                      ASL_Pattern,(ULONG)"#?.lfpic",
  563.                                      ASL_File,(ULONG) vorschlag,TAG_END))
  564.   {
  565.      sprintf((char *)dateiname,"%s/%s",
  566.              (char *) file_req->rf_Dir,(char *) file_req->rf_File);
  567.  
  568.      start_busy(Window);  /* Make Window Busy */
  569.  
  570.     if(pic_handle=Open(dateiname,MODE_NEWFILE)) {
  571.        SetTitle(Window,(UBYTE *) "Saving...");
  572.        Write(pic_handle,(UBYTE *) &Scale,2L);
  573.        Write(pic_handle,(UBYTE *) &win_right,2L);
  574.       for(y=win_top;y<=win_bottom;y++) {
  575.         for(x=xlast=win_left;x<=win_right;x++)
  576.           if(color != (SHORT) ReadPixel(rp,x,y)) {
  577.             if (pix_anzahl = (x-xlast)<<1) {
  578.                pix_anzahl |= color;
  579.                Write(pic_handle,(UBYTE *) &pix_anzahl,2L);
  580.                xlast=x;
  581.             }
  582.              color=!color;
  583.           }
  584.          pix_anzahl = ((x-xlast)<<1) | color;
  585.          Write(pic_handle,(UBYTE *) &pix_anzahl,2L);
  586.       }
  587.        Close(pic_handle);
  588.     }
  589.      end_busy(Window); std_title();   /* Unbusy Window */
  590.   }
  591. }
  592.  
  593. /*****************************************************************************/
  594. /* printer        (Druckt das momentan angezeigte Fractal)                   */
  595. /*****************************************************************************/
  596. void printer(Item item,Event event)
  597. {
  598.  SHORT dbarheight;
  599.  
  600.   if(bool_request(Window,get_catstr(PRINTOK_STR),
  601.                   get_catstr(YES_STR),get_catstr(NOTYET_STR))) {
  602.      dbarheight = Window->WScreen->WBorTop + Window->WScreen->Font->ta_YSize;
  603.      SetTitle(Window,(UBYTE *) "Printing...");
  604.      start_busy(Window);
  605.      win_print(Window,(UWORD)(Window->LeftEdge+4),(UWORD)(dbarheight + 1),
  606.                (UWORD)(Window->Width-8),(UWORD)(Window->Height - dbarheight - 3),
  607.                20,YScale);
  608.      end_busy(Window); std_title();
  609.   }
  610. }
  611.  
  612. /*****************************************************************************/
  613. /* load_code/save_code (Lädt/Speichert den Code zu einem bestimmten Fractal) */
  614. /*****************************************************************************/
  615. void load_code(Item item,Event event)
  616. {
  617.  COUNT i;
  618.  UBYTE dateiname[DATANAMESIZE],ptr[2],*gad_info;
  619.  ULONG codehandle;
  620.  
  621.    sprintf((char *)dateiname,"%s/%s.code",
  622.            (char *)(file_req->rf_Dir),get_STGADinfo(NAME_GAD));
  623.  
  624.   if(codehandle=Open(dateiname,MODE_OLDFILE)) {
  625.      i=0;
  626.     while(Read(codehandle,ptr,1L))
  627.       if(ptr[0]=='/') {
  628.          gad_info  = get_STGADinfo(AXIOM_GAD+i);
  629.          strcpy((char *)gad_info,"");
  630.          i++;
  631.       }else strncat((char *)gad_info,(char *)ptr,1L);
  632.     for(;i<=CODEZAHL;i++) set_STGADinfo(AXIOM_GAD+i,(UBYTE *) "");
  633.      Close(codehandle);
  634.   }
  635.    RefreshGadgets(get_gadadr(AXIOM_GAD),Window,&new_req);
  636. }
  637.  
  638. void save_code(Item item,Event event)
  639. {
  640.  COUNT i;
  641.  UBYTE dateiname[DATANAMESIZE],*ptr;
  642.  ULONG codehandle;
  643.  
  644.    sprintf((char *)dateiname,"FracsCodes/%s.code",get_STGADinfo(NAME_GAD));
  645.  
  646.   if(codehandle=Open(dateiname,MODE_NEWFILE)) {
  647.     for(i=0;i<=CODEZAHL;i++) {
  648.        ptr=(UBYTE *) get_STGADinfo(AXIOM_GAD+i);
  649.       if(*ptr!=0) {
  650.          Write(codehandle,"/",1L);
  651.          Write(codehandle,ptr,(long) strlen((char *)ptr));
  652.       }
  653.     }
  654.      Close(codehandle);
  655.   }
  656. }
  657.  
  658. /*****************************************************************************/
  659. /* dir_code  (Aus der Liste aller bereits gespeicherten Fractal-Code-Files   */
  660. /*            kann ein bestimmtes File ausgewählt werden)                    */
  661. /*****************************************************************************/
  662. void dir_code(Item item,Event event)
  663. {
  664.  UBYTE *gad_info;
  665.  
  666.   if (AslRequestTags((APTR)file_req,ASL_Dir,(ULONG)"FracsCodes",
  667.                                     ASL_Hail,(ULONG)get_catstr(SELCODEFILE_STR),
  668.                                     ASL_Pattern,(ULONG)"#?.code",
  669.                                     ASL_File,(ULONG)"#?.code",TAG_END))
  670.   {
  671.      gad_info = get_STGADinfo(NAME_GAD);
  672.      strcpy((char *)gad_info,(char *)file_req->rf_File);
  673.      gad_info[strlen((char *)file_req->rf_File)-5] = 0; /*Schneide .code ab*/
  674.      RefreshGadgets(get_gadadr(NAME_GAD),Window,&new_req);
  675.      load_code(GF_NULL,GF_NULL);
  676.   }
  677. }